package cn.iocoder.yudao.module.member.service.memberconf;

import cn.iocoder.yudao.framework.common.enums.member.AutoReminderTypeEnum;
import cn.iocoder.yudao.framework.common.enums.metal.MetalTypeEnum;
import cn.iocoder.yudao.framework.common.enums.trade.TransactionTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.member.api.config.dto.MemberConfMaterialDTO;
import cn.iocoder.yudao.module.member.api.config.dto.MemberConfRespDTO;
import cn.iocoder.yudao.module.member.controller.admin.confadditionalfee.vo.MemberConfAdditionalFeeRespVO;
import cn.iocoder.yudao.module.member.controller.admin.confmaterial.vo.MemberConfMaterialRespVO;
import cn.iocoder.yudao.module.member.controller.admin.confmaterial.vo.MemberConfMaterialSaveReqVO;
import cn.iocoder.yudao.module.member.controller.admin.confpoint.vo.MemberConfPointRespVO;
import cn.iocoder.yudao.module.member.controller.admin.confpoint.vo.MemberConfPointSaveReqVO;
import cn.iocoder.yudao.module.member.controller.admin.confrebate.vo.MemberConfRebateRespVO;
import cn.iocoder.yudao.module.member.controller.admin.confrebate.vo.MemberConfRebateSaveReqVO;
import cn.iocoder.yudao.module.member.controller.admin.memberconf.vo.MemberConfPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.memberconf.vo.MemberConfRespVO;
import cn.iocoder.yudao.module.member.controller.admin.memberconf.vo.MemberConfSaveReqVO;
import cn.iocoder.yudao.module.member.convert.config.MemberConfConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.memberconf.MemberConfDO;
import cn.iocoder.yudao.module.member.dal.dataobject.memberconf.confadditionalfee.MemberConfAdditionalFeeDO;
import cn.iocoder.yudao.module.member.dal.dataobject.memberconf.confmaterial.MemberConfMaterialDO;
import cn.iocoder.yudao.module.member.dal.dataobject.memberconf.confpoint.MemberConfPointDO;
import cn.iocoder.yudao.module.member.dal.dataobject.memberconf.confrebate.MemberConfRebateDO;
import cn.iocoder.yudao.module.member.dal.mysql.memberconf.MemberConfMapper;
import cn.iocoder.yudao.module.member.dal.mysql.memberconf.confadditionalfee.MemberConfAdditionalFeeMapper;
import cn.iocoder.yudao.module.member.dal.mysql.memberconf.confmaterial.MemberConfMaterialMapper;
import cn.iocoder.yudao.module.member.dal.mysql.memberconf.confpoint.MemberConfPointMapper;
import cn.iocoder.yudao.module.member.dal.mysql.memberconf.confrebate.MemberConfRebateMapper;
import cn.iocoder.yudao.module.member.enums.conf.*;
import jakarta.annotation.Resource;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;

/**
 * 会员主配置 Service 实现类
 *
 * @author doock
 */
@Service
@Validated
public class MemberConfServiceImpl implements MemberConfService {

    @Resource
    private MemberConfMapper confMapper;
    @Resource
    private MemberConfMaterialMapper confMaterialMapper;
    @Resource
    private MemberConfPointMapper confPointMapper;
    @Resource
    private MemberConfRebateMapper confRebateMapper;
    @Resource
    private MemberConfAdditionalFeeMapper confAdditionalFeeMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createConf(MemberConfSaveReqVO createReqVO) {
        // 设置枚举字段的默认值
        setEnumDefaults(createReqVO);
        
        // 校验枚举值的有效性
        validateEnums(createReqVO);
        
        // 校验唯一性约束
        validateUnique(createReqVO);
        
        // 插入
        MemberConfDO conf = BeanUtils.toBean(createReqVO, MemberConfDO.class);
        confMapper.insert(conf);

        // 插入子表
        createOrUpdateMemberConfMaterialList(conf.getId(), createReqVO.getConfMaterials());
        // 返回
        return conf.getId();
    }
    
    /**
     * 设置会员配置枚举字段的默认值
     *
     * @param reqVO 会员配置请求对象
     */
    private void setEnumDefaults(MemberConfSaveReqVO reqVO) {
        // 主配置枚举字段默认值
        if (reqVO.getAutoReminder() == null) {
            reqVO.setAutoReminder(AutoReminderTypeEnum.NONE.getType());
        }
        if (reqVO.getSettlementMethod() == null) {
            reqVO.setSettlementMethod(SettlementMethodEnum.SINGLE.getType());
        }
        
        // 物料策略配置枚举字段默认值
        if (reqVO.getConfMaterials() != null) {
            for (MemberConfMaterialSaveReqVO material : reqVO.getConfMaterials()) {
                // 策略类型默认值
                if (material.getPolicyType() == null) {
                    material.setPolicyType(TransactionTypeEnum.FULL_PAY_BUY.getType());
                }
                // 金属类型默认值
                if (material.getMetalType() == null) {
                    material.setMetalType(MetalTypeEnum.GOLD.getType());
                }
                
                // 积分规则配置枚举字段默认值
                if (material.getConfPoints() != null) {
                    for (MemberConfPointSaveReqVO point : material.getConfPoints()) {
                        // 交易类型默认值
                        if (point.getTransactionType() == null) {
                            point.setTransactionType(PointTransactionTypeEnum.PHYSICAL_METAL_BUY.getType());
                        }
                        // 金属类型默认值
                        if (point.getMetalType() == null) {
                            point.setMetalType(MetalTypeEnum.GOLD.getType());
                        }
                        // 计算单位类型默认值
                        if (point.getPerType() == null) {
                            point.setPerType(PointPerTypeEnum.BY_GRAM.getType());
                        }
                    }
                }
                
                // 返佣政策配置枚举字段默认值
                if (material.getConfRebates() != null) {
                    for (MemberConfRebateSaveReqVO rebate : material.getConfRebates()) {
                        // 返佣对象默认值
                        if (rebate.getRebateType() == null) {
                            rebate.setRebateType(RebateTypeEnum.AGENT_COMPANY.getType());
                        }
                        // 返佣节点默认值
                        if (rebate.getActionType() == null) {
                            rebate.setActionType(RebateActionTypeEnum.PRICE_SETTLEMENT.getType());
                        }
                    }
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "member_conf_cache", key = "'conf_id:' + #updateReqVO.id")
    public void updateConf(MemberConfSaveReqVO updateReqVO) {
        // 校验存在
        validateConfExists(updateReqVO.getId());
        
        // 校验枚举值的有效性
        validateEnums(updateReqVO);
        
        // 校验唯一性约束
        validateUnique(updateReqVO);
        
        // 更新
        MemberConfDO updateObj = BeanUtils.toBean(updateReqVO, MemberConfDO.class);
        confMapper.updateById(updateObj);

        // 更新子表
        updateMemberConfMaterialList(updateReqVO.getId(), updateReqVO.getConfMaterials());
    }

    /**
     * 校验唯一性约束
     *
     * @param reqVO 会员配置请求对象
     */
    private void validateUnique(MemberConfSaveReqVO reqVO) {
        // 1. 校验会员ID唯一性
        validateUserIdUnique(reqVO);
        
        // 2. 校验物料策略配置唯一性
        if (reqVO.getConfMaterials() != null && !reqVO.getConfMaterials().isEmpty()) {
            // 检查物料策略的policy_type和metal_type组合唯一性
            validateMaterialsUnique(reqVO.getConfMaterials());
            
            // 校验每个物料策略内部的子配置唯一性
            for (MemberConfMaterialSaveReqVO material : reqVO.getConfMaterials()) {
                // 检查积分规则的transaction_type和metal_type组合唯一性
                if (material.getConfPoints() != null && !material.getConfPoints().isEmpty()) {
                    validatePointsUnique(material.getConfPoints());
                }
                
                // 检查返佣政策的rebate_type和action_type组合唯一性
                if (material.getConfRebates() != null && !material.getConfRebates().isEmpty()) {
                    validateRebatesUnique(material.getConfRebates());
                }
                
                // 检查阶梯费用配置的唯一性（每个物料策略最多一个）
                if (material.getConfAdditionalFees() != null && material.getConfAdditionalFees().size() > 1) {
                    throw exception(CONF_ADDITIONAL_FEE_DUPLICATE);
                }
            }
        }
    }

    /**
     * 校验会员ID唯一性
     *
     * @param reqVO 会员配置请求VO
     */
    private void validateUserIdUnique(MemberConfSaveReqVO reqVO) {
        if (reqVO.getUserId() == null) {
            return;
        }
        
        // 查询是否已存在该会员的配置
        MemberConfDO existingConf = confMapper.selectByUserId(reqVO.getUserId());
        if (existingConf != null && !existingConf.getId().equals(reqVO.getId())) {
            throw exception(CONF_USER_ID_DUPLICATE);
        }
    }

    /**
     * 校验物料策略配置的policy_type和metal_type组合唯一性
     *
     * @param materials 物料策略配置列表
     */
    private void validateMaterialsUnique(List<MemberConfMaterialSaveReqVO> materials) {
        // 使用Set来检测重复组合
        Set<String> uniqueKeys = new HashSet<>();
        for (MemberConfMaterialSaveReqVO material : materials) {
            if (material.getPolicyType() != null && material.getMetalType() != null) {
                String key = material.getPolicyType() + ":" + material.getMetalType();
                if (!uniqueKeys.add(key)) {
                    throw exception(CONF_MATERIAL_DUPLICATE);
                }
            }
        }
    }

    /**
     * 校验积分规则的transaction_type和metal_type组合唯一性
     *
     * @param points 积分规则列表
     */
    private void validatePointsUnique(List<MemberConfPointSaveReqVO> points) {
        // 使用Set来检测重复组合
        Set<String> uniqueKeys = new HashSet<>();
        for (MemberConfPointSaveReqVO point : points) {
            if (point.getTransactionType() != null && point.getMetalType() != null) {
                String key = point.getTransactionType() + ":" + point.getMetalType();
                if (!uniqueKeys.add(key)) {
                    throw exception(CONF_POINT_DUPLICATE);
                }
            }
        }
    }

    /**
     * 校验返佣政策的rebate_type和action_type组合唯一性
     *
     * @param rebates 返佣政策列表
     */
    private void validateRebatesUnique(List<MemberConfRebateSaveReqVO> rebates) {
        // 使用Set来检测重复组合
        Set<String> uniqueKeys = new HashSet<>();
        for (MemberConfRebateSaveReqVO rebate : rebates) {
            if (rebate.getRebateType() != null && rebate.getActionType() != null) {
                String key = rebate.getRebateType() + ":" + rebate.getActionType();
                if (!uniqueKeys.add(key)) {
                    throw exception(CONF_REBATE_DUPLICATE);
                }
            }
        }
    }

    /**
     * 校验枚举值的有效性
     *
     * @param reqVO 会员配置请求对象
     */
    private void validateEnums(MemberConfSaveReqVO reqVO) {
        // 校验主表枚举值
        if (reqVO.getAutoReminder() != null) {
            boolean validAutoReminder = Arrays.stream(AutoReminderTypeEnum.values())
                    .anyMatch(item -> item.getType().equals(reqVO.getAutoReminder()));
            if (!validAutoReminder) {
                throw exception(CONF_AUTO_REMINDER_TYPE_ERROR);
            }
        }

        if (reqVO.getSettlementMethod() != null) {
            boolean validSettlementMethod = Arrays.stream(SettlementMethodEnum.values())
                    .anyMatch(item -> item.getType().equals(reqVO.getSettlementMethod()));
            if (!validSettlementMethod) {
                throw exception(CONF_SETTLEMENT_METHOD_ERROR);
            }
        }

        // 校验物料策略配置的枚举值
        if (reqVO.getConfMaterials() != null && !reqVO.getConfMaterials().isEmpty()) {
            for (MemberConfMaterialSaveReqVO material : reqVO.getConfMaterials()) {
                // 校验策略类型
                if (material.getPolicyType() != null) {
                    boolean validPolicyType = Arrays.stream(TransactionTypeEnum.values())
                            .anyMatch(item -> item.getType().equals(material.getPolicyType()));
                    if (!validPolicyType) {
                        throw exception(CONF_MATERIAL_POLICY_TYPE_ERROR);
                    }
                }

                // 校验金属类型
                if (material.getMetalType() != null) {
                    boolean validMetalType = Arrays.stream(MetalTypeEnum.values())
                            .anyMatch(item -> item.getType().equals(material.getMetalType()));
                    if (!validMetalType) {
                        throw exception(CONF_MATERIAL_METAL_TYPE_ERROR);
                    }
                }

                // 校验积分规则的枚举值
                if (material.getConfPoints() != null && !material.getConfPoints().isEmpty()) {
                    for (MemberConfPointSaveReqVO point : material.getConfPoints()) {
                        // 校验交易类型
                        if (point.getTransactionType() != null) {
                            boolean validTransactionType = Arrays.stream(PointTransactionTypeEnum.values())
                                    .anyMatch(item -> item.getType().equals(point.getTransactionType()));
                            if (!validTransactionType) {
                                throw exception(CONF_POINT_TRANSACTION_TYPE_ERROR);
                            }
                        }

                        // 校验金属类型
                        if (point.getMetalType() != null) {
                            boolean validMetalType = Arrays.stream(MetalTypeEnum.values())
                                    .anyMatch(item -> item.getType().equals(point.getMetalType()));
                            if (!validMetalType) {
                                throw exception(CONF_POINT_METAL_TYPE_ERROR);
                            }
                        }

                        // 校验计算单位类型
                        if (point.getPerType() != null) {
                            boolean validPerType = Arrays.stream(PointPerTypeEnum.values())
                                    .anyMatch(item -> item.getType().equals(point.getPerType()));
                            if (!validPerType) {
                                throw exception(CONF_POINT_PER_TYPE_ERROR);
                            }
                        }
                    }
                }

                // 校验返佣政策的枚举值
                if (material.getConfRebates() != null && !material.getConfRebates().isEmpty()) {
                    for (MemberConfRebateSaveReqVO rebate : material.getConfRebates()) {
                        // 校验返佣对象
                        if (rebate.getRebateType() != null) {
                            boolean validRebateType = Arrays.stream(RebateTypeEnum.values())
                                    .anyMatch(item -> item.getType().equals(rebate.getRebateType()));
                            if (!validRebateType) {
                                throw exception(CONF_REBATE_TYPE_ERROR);
                            }
                        }

                        // 校验返佣节点
                        if (rebate.getActionType() != null) {
                            boolean validActionType = Arrays.stream(RebateActionTypeEnum.values())
                                    .anyMatch(item -> item.getType().equals(rebate.getActionType()));
                            if (!validActionType) {
                                throw exception(CONF_REBATE_ACTION_TYPE_ERROR);
                            }
                        }
                    }
                }
            }
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteConf(Long id) {
        // 校验存在
        validateConfExists(id);
        // 删除
        confMapper.deleteById(id);

        // 删除子表
        deleteMemberConfMaterialByMemberConfId(id);
    }

    private void validateConfExists(Long id) {
        if (confMapper.selectById(id) == null) {
            throw exception(CONF_NOT_EXISTS);
        }
    }

    @Override
    public MemberConfDO getConf(Long id) {
        return confMapper.selectById(id);
    }

    @Override
    public MemberConfRespVO getConfDetail(Long id) {
        // 获取主配置
        MemberConfDO conf = confMapper.selectById(id);
        if (conf == null) {
            return null;
        }

        // 转换为响应对象
        MemberConfRespVO respVO = BeanUtils.toBean(conf, MemberConfRespVO.class);

        // 获取物料策略配置
        List<MemberConfMaterialDO> materialList = getConfMaterialListByMemberConfId(id);
        respVO.setConfMaterials(BeanUtils.toBean(materialList, MemberConfMaterialRespVO.class));

        // 获取物料策略关联的积分规则、返佣政策、阶梯费用
        if (!materialList.isEmpty()) {
            // 获取物料策略ID列表
            List<Long> materialIds = materialList.stream()
                    .map(MemberConfMaterialDO::getId)
                    .collect(Collectors.toList());

            // 获取并关联积分规则
            List<MemberConfPointDO> pointList = getConfPointListByMaterialIds(materialIds);
            Map<Long, List<MemberConfPointDO>> pointMap = pointList.stream()
                    .collect(Collectors.groupingBy(MemberConfPointDO::getMaterialPolicyId));

            // 获取并关联返佣政策
            List<MemberConfRebateDO> rebateList = getConfRebateListByMaterialIds(materialIds);
            Map<Long, List<MemberConfRebateDO>> rebateMap = rebateList.stream()
                    .collect(Collectors.groupingBy(MemberConfRebateDO::getMaterialPolicyId));

            // 获取并关联阶梯费用
            List<MemberConfAdditionalFeeDO> feeList = getConfAdditionalFeeListByMaterialIds(materialIds);
            Map<Long, List<MemberConfAdditionalFeeDO>> feeMap = feeList.stream()
                    .collect(Collectors.groupingBy(MemberConfAdditionalFeeDO::getMaterialPolicyId));

            // 设置关联关系
            for (MemberConfMaterialRespVO material : respVO.getConfMaterials()) {
                Long materialId = material.getId();
                material.setConfPoints(BeanUtils.toBean(pointMap.getOrDefault(materialId, new ArrayList<>()), MemberConfPointRespVO.class));
                material.setConfRebates(BeanUtils.toBean(rebateMap.getOrDefault(materialId, new ArrayList<>()), MemberConfRebateRespVO.class));
                material.setConfAdditionalFees(BeanUtils.toBean(feeMap.getOrDefault(materialId, new ArrayList<>()), MemberConfAdditionalFeeRespVO.class));
            }
        }

        return respVO;
    }

    @Override
    public PageResult<MemberConfDO> getConfPage(MemberConfPageReqVO pageReqVO) {
        return confMapper.selectPage(pageReqVO);
    }

    // ==================== 物料策略配置 ====================

    @Override
    @Cacheable(cacheNames = "member_conf_cache", key = "'conf_id:' + #tradeConfId + ';materia_list'")
    public List<MemberConfMaterialDO> getConfMaterialListByMemberConfId(Long tradeConfId) {
        return confMaterialMapper.selectListByMemberConfId(tradeConfId);
    }

    @Override
    @Cacheable(cacheNames = "member_conf_cache", key = "'conf_id:1'")
    public MemberConfDO getConfDefault() {
        MemberConfDO confDO = confMapper.selectOne(MemberConfDO::getId, 1);
        if (confDO == null) {
            throw exception(CONF_NOT_EXISTS);
        }
        return confDO;
    }

    private void createOrUpdateMemberConfMaterialList(Long tradeConfId, List<MemberConfMaterialSaveReqVO> list) {
        if (list == null || list.isEmpty()) {
            return;
        }

        // 设置关联的主配置ID
        list.forEach(o -> o.setMemberConfId(tradeConfId));

        // 插入物料策略配置
        List<MemberConfMaterialDO> materialList = BeanUtils.toBean(list, MemberConfMaterialDO.class);
        confMaterialMapper.insertOrUpdate(materialList);

        // 处理物料策略的子表关联
        for (int i = 0; i < list.size(); i++) {
            Long materialId = materialList.get(i).getId();
            MemberConfMaterialSaveReqVO materialReqVO = list.get(i);

            // 创建关联的积分规则
            List<MemberConfPointDO> pointList = BeanUtils.toBean(materialReqVO.getConfPoints(), MemberConfPointDO.class);
            createMemberConfPointList(materialId, pointList);

            // 创建关联的返佣政策
            List<MemberConfRebateDO> rebateList = BeanUtils.toBean(materialReqVO.getConfRebates(), MemberConfRebateDO.class);
            createMemberConfRebateList(materialId, rebateList);

            // 创建关联的阶梯费用
            List<MemberConfAdditionalFeeDO> feeList = BeanUtils.toBean(materialReqVO.getConfAdditionalFees(), MemberConfAdditionalFeeDO.class);
            createMemberConfAdditionalFeeList(materialId, feeList);
        }
    }

    private void updateMemberConfMaterialList(Long tradeConfId, List<MemberConfMaterialSaveReqVO> list) {
//        // 查询旧的物料策略列表
//        List<MemberConfMaterialDO> oldList = confMaterialMapper.selectListByMemberConfId(tradeConfId);

        // 删除旧的物料策略及其关联的子表
//        if (!oldList.isEmpty()) {
//            List<Long> oldMaterialIds = oldList.stream().map(MemberConfMaterialDO::getId).collect(Collectors.toList());
//            oldMaterialIds.forEach(this::deleteMemberConfMaterialSubTables);
//            confMaterialMapper.deleteByMemberConfId(tradeConfId);
//        }

        // 创建新的物料策略及其关联的子表
        createOrUpdateMemberConfMaterialList(tradeConfId, list);
    }

    private void deleteMemberConfMaterialByMemberConfId(Long tradeConfId) {
        // 查询物料策略列表
        List<MemberConfMaterialDO> materialList = confMaterialMapper.selectListByMemberConfId(tradeConfId);

        // 删除物料策略关联的子表
        materialList.forEach(material -> deleteMemberConfMaterialSubTables(material.getId()));

        // 删除物料策略
        confMaterialMapper.deleteByMemberConfId(tradeConfId);
    }

    private void deleteMemberConfMaterialSubTables(Long materialId) {
        // 删除积分规则
        confPointMapper.deleteByMaterialPolicyId(materialId);

        // 删除返佣政策
        confRebateMapper.deleteByMaterialPolicyId(materialId);

        // 删除阶梯费用
        confAdditionalFeeMapper.deleteByMaterialPolicyId(materialId);
    }

    // ==================== 积分规则配置 ====================

    @Override
    public List<MemberConfPointDO> getConfPointListByMaterialIds(List<Long> materialIds) {
        return confPointMapper.selectListByMaterialPolicyIds(materialIds);
    }

    @Override
    public List<MemberConfPointDO> createMemberConfPointList(Long materialId, List<MemberConfPointDO> list) {
        if (list == null || list.isEmpty()) {
            return list;
        }

        // 设置关联的物料策略ID
        list.forEach(o -> o.setMaterialPolicyId(materialId));

        // 插入积分规则
        confPointMapper.insertOrUpdate(list);
        return this.getConfPointListByMaterialId(materialId);
    }

    // ==================== 返佣政策配置 ====================

    @Override
    public List<MemberConfRebateDO> getConfRebateListByMaterialIds(List<Long> materialIds) {
        return confRebateMapper.selectListByMaterialPolicyIds(materialIds);
    }

    @Override
    public List<MemberConfRebateDO> createMemberConfRebateList(Long materialId, List<MemberConfRebateDO> list) {
        if (list == null || list.isEmpty()) {
            return list;
        }

        // 设置关联的物料策略ID
        list.forEach(o -> o.setMaterialPolicyId(materialId));

        // 插入返佣政策
        confRebateMapper.insertOrUpdate(list);
        return this.getConfRebateListByMaterialId(materialId);
    }

    // ==================== 阶梯费用配置 ====================
    @Override
    public List<MemberConfAdditionalFeeDO> getConfAdditionalFeeListByMaterialIds(List<Long> materialIds) {
        return confAdditionalFeeMapper.selectListByMaterialPolicyIds(materialIds);
    }

    @Override
    public List<MemberConfAdditionalFeeDO> createMemberConfAdditionalFeeList(Long materialId, List<MemberConfAdditionalFeeDO> list) {
        if (list == null || list.isEmpty()) {
            return null;
        }

        // 设置关联的物料策略ID
        list.forEach(o -> o.setMaterialPolicyId(materialId));

        // 插入阶梯费用
        confAdditionalFeeMapper.insertOrUpdate(list);
        return this.getConfAdditionalFeeListByMaterialId(materialId);
    }

    @Override
    public MemberConfDO saveConf(MemberConfDO confDO) {
        confMapper.insert(confDO);
        return confDO;
    }

    @Override
    public MemberConfMaterialDO saveMaterialConf(MemberConfMaterialDO confDO) {
        confMaterialMapper.insert(confDO);
        return confDO;
    }

    @Override
    public List<MemberConfAdditionalFeeDO> getConfAdditionalFeeListByMaterialId(Long originMaterialConfId) {
        return confAdditionalFeeMapper.selectListByMaterialPolicyId(originMaterialConfId);
    }

    @Override
    public List<MemberConfRebateDO> getConfRebateListByMaterialId(Long originMaterialConfId) {
        return confRebateMapper.selectListByMaterialPolicyId(originMaterialConfId);
    }

    @Override
    public List<MemberConfPointDO> getConfPointListByMaterialId(Long originMaterialConfId) {
        return confPointMapper.selectListByMaterialPolicyId(originMaterialConfId);
    }

    @Override
    public MemberConfDO getConfByUser(Long userId) {
        return confMapper.selectByUserId(userId);
    }

    @Override
    @Cacheable(cacheNames = "member_conf_cache", key = "'conf_id:' + #id")
    public MemberConfRespDTO getMemberConf(Long id) {
        MemberConfDO confDO;
        if (id != null) {
            confDO = getConf(id);
        } else {
            confDO = getConfDefault();
        }
        List<MemberConfMaterialDO> materialDOList = getConfMaterialListByMemberConfId(confDO.getId());
        List<MemberConfMaterialDTO> materialDTOList = new ArrayList<>(materialDOList.size());
        // 处理物料策略的子表关联
        for (MemberConfMaterialDO materialDO : materialDOList) {
            // 获取现有配置
            Long materialConfId = materialDO.getId();
            List<MemberConfPointDO> confPointList = getConfPointListByMaterialId(materialConfId);
            List<MemberConfRebateDO> confRebateList = getConfRebateListByMaterialId(materialConfId);
            List<MemberConfAdditionalFeeDO> confAdditionalFeeList = getConfAdditionalFeeListByMaterialId(materialConfId);
            materialDTOList.add(MemberConfConvert.INSTANCE.convertMaterialDTO(materialDO, confPointList, confRebateList, confAdditionalFeeList));
        }
        return MemberConfConvert.INSTANCE.convertDTO(confDO, materialDTOList);
    }

}